package org.tp.edifact.syntax;

import static org.junit.Assert.*;

import org.junit.Test;

public class TestDefaultV3UNOBCharacterSet {

   //| Default service characters in Level A syntax for version 3.
   
   private final static char[] SERVICE_CHARACTERS = {(char) 0x1f, (char) 0x1d, (char) 0x1c};
   private final static ECharacterClass[] SERVICE_CHARACTER_IDS = {
      ECharacterClass.COMPONENT_DATA_ELEMENT_SEPARATOR,
      ECharacterClass.DATA_ELEMENT_SEPARATOR,
      ECharacterClass.SEGMENT_TERMINATOR
   };
   
   @Test
   public void testIsServiceCharacter() {
      DefaultV3UNOBCharacterSet scs = new DefaultV3UNOBCharacterSet();
      int serviceCharacterCount = 0;
      
      char c;
      
      for(int i = 0; i <= 255; i++) {
         c = (char) (i & 0xff);

         if (scs.isServiceCharacter(c)) {
            serviceCharacterCount++;
         }
      }
      
      //| Must be 4 service characters.
      
      assertEquals(
            "Wrong number of service characters",
            SERVICE_CHARACTERS.length,
            serviceCharacterCount);  
      
      //| Check that service characters are actually service characters.
      
      for (int i = 0; i < SERVICE_CHARACTERS.length; i++) {
         assertTrue(
               "Character " + SERVICE_CHARACTERS[i] + " shall be a service character.",
               scs.isServiceCharacter(SERVICE_CHARACTERS[i]));           
      }
   }
   
   @Test
   public void testGetServiceCharacterIdentifier() {
      DefaultV3UNOBCharacterSet scs = new DefaultV3UNOBCharacterSet();
      
      for (int i = 0; i < SERVICE_CHARACTERS.length; i++) {
         assertEquals(
               "Wrong character identifier for character: " + (int) SERVICE_CHARACTERS[i],
               SERVICE_CHARACTER_IDS[i],
               scs.getCharacterClass(SERVICE_CHARACTERS[i]));
      }
      
      char c;
      
      for(int i = 0; i <= 255; i++) {
         c = (char) (i & 0xff);

         if (!scs.isServiceCharacter(c)) {
            assertEquals(
                  "Wrong service character: " + c,
                  ECharacterClass.DATA_CHARACTER,
                  scs.getCharacterClass(c));
         }
      }
   }
   
   @Test
   public void testGetServiceCharacter() {
      DefaultV3UNOBCharacterSet scs = new DefaultV3UNOBCharacterSet();

      for (int i = 0; i < SERVICE_CHARACTER_IDS.length; i++) {
         assertEquals(
               "Wrong service character identifier: " + SERVICE_CHARACTER_IDS[i],
               SERVICE_CHARACTERS[i],
               scs.getServiceCharacter(SERVICE_CHARACTER_IDS[i]));
         
      }
   }
   
   @Test
   public void testGetServiceCharacterSet() {
      DefaultV3UNOBCharacterSet scs = new DefaultV3UNOBCharacterSet();
      
      char[] s = scs.getServiceCharacterSet();
      
      for (int i = 0; i < s.length; i++) {
         assertEquals(
               "Wrong service character at position: "
                  + i,
                  DefaultV3UNOBCharacterSet.DEFAULT_SERVICE_CHARACTER_SET[i],
               s[i]);
      }
         
      char[] s2 = scs.getServiceCharacterSet();
      
      assertNotEquals(
            "Same array object returned",
            s,
            s2);
      
      s[5] = '@';
      s2 = scs.getServiceCharacterSet();

      assertNotEquals(
            "Changed object contents.",
            s[5],
            s2[5]);
   }
   
   @Test
   public void testHasMethods() {
      DefaultV3UNOBCharacterSet scs = new DefaultV3UNOBCharacterSet();

      assertFalse(
            "This character set must not have release indicator.",
            scs.hasReleaseIndicator());

      assertFalse(
            "This character set must not have repetition separator.",
            scs.hasRepetitionSeparator());
   }
   
}
